package com.zwh.config;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

/**
 * @Pointcut：切入点
 * @Before: 前置通知, 在方法执行之前执行
 * @After: 后置通知, 在方法执行之后执行 。
 * @AfterRunning: 返回通知, 在方法返回结果之后执行
 * @AfterThrowing: 异常通知, 在方法抛出异常之后
 * @Around: 环绕通知, 围绕着方法执行
 */

@Component
@Aspect
public class AopConfig {

    @Pointcut("execution(public int com.zwh.service.IAopService.add(..))")
    public void myPoint(){}


    @Before("execution(* com.zwh.controller.AopController.add(..))")
    public void before(){
        System.out.println("前置通知");
    }

    @After("execution(* com.zwh.service.IAopService.add(..))")
    public void after(){
        System.out.println("后置通知");
    }

    @Around(value = "myPoint()")
    public Object around( ProceedingJoinPoint pjp) throws Throwable {
        Object[] args = pjp.getArgs();
        String name = pjp.getSignature().getName();
        Object proceed=null;
        try {
            //@Before
            System.out.println("【环绕前置通知】【"+name+"方法开始】");
            /*这句相当于method.invoke(obj,args)，通过反射来执行接口中的方法;因此在反射执行完方法后会有一个返回值proceed*/
            proceed = pjp.proceed();
            //@AfterReturning
            System.out.println("【环绕返回通知】【"+name+"方法返回，返回值："+proceed+"】");
        } catch (Exception e) {
            //@AfterThrowing
            System.out.println("【环绕异常通知】【"+name+"方法异常，异常信息："+e+"】");
        }finally{
            //@After
            System.out.println("【环绕后置通知】【"+name+"方法结束】");
        }
        return proceed;
    }
}
